//
//  ARTranslateUtil.swift
//  AquaRaft
//
//  Created by 何启亮 on 2024/4/22.
//

import Foundation
import Cache
import Alamofire

class ARTranslateUtil {
    
    // MARK: - Property
    
    private var storage: Storage<String, String>?
    private static let storageName = "AR_translateUtil_storage_name"
    
    var translateKey: String?
    
    // MARK: - Shared
    
    static let share = ARTranslateUtil()
    
    private init() {
        // 设置
        
        storage = try? Storage(diskConfig: DiskConfig(name: Self.storageName), memoryConfig: MemoryConfig(), transformer: TransformerFactory.forCodable(ofType: String.self))
    }
    
    // get方法 - 同步、异步
    
    func translatedTextFor(_ string: String) -> String? {
        return try? storage?.object(forKey: string)
    }
    
    /// 翻译
    func translate(_ q: String, completion: @escaping (ARRequestResult<String>) -> Void) {
        if let text = translatedTextFor(q) {
            completion(.success(model: text))
            return
        }
        guard let key = translateKey else {
            completion(.faild(err: .normalError))
            return
        }
        __TranslateRequest().translate(q, key: key, targetLanguageCode: ARHelper.systemLanguageCode()) { [weak self] result in
            // 先记录
            switch result {
            case .faild(let err):
                completion(.faild(err: err))
            case .successWithoutResponse:
                completion(.faild(err: .modelConvertError(error: nil)))
            case .success(let model):
                // 记录
                try? self?.storage?.setObject(model, forKey: q)
                completion(.success(model: model))
            }
        }
    }
}

// MARK: - Other

fileprivate struct __TranslateResponse: Decodable {
    
    let translations: [__TranslateModel]
    
}

fileprivate struct __TranslateModel: Decodable {
    let translatedText: String
    let detectedSourceLanguage: String
}

fileprivate class __TranslateRequest {
    
    /// 翻译
    func translate(_ q: String, key: String, targetLanguageCode: String, completion: @escaping (ARRequestResult<String>) -> Void) {
        
        let url = "https://translation.googleapis.com/language/translate/v2"
        let params = [
            "q": q,
            "key" : key,
            "target" : targetLanguageCode,
            "format" : "text"
        ]
        AF.request(url, method: .post, parameters: params, encoding: JSONEncoding.default).responseDecodable(of: AnyDecodable.self) { responseResult in
            switch responseResult.result {
            case .failure(let err):
                completion(.faild(err: .serviceError(error: err)))
            case .success(let responseModel):
                // 判断是否有data
                guard case let .dictionary(dict) = responseModel,
                      case let .dictionary(data) = dict["data"] else {
                    completion(.faild(err: .modelConvertError(error: nil)))
                    return
                }
                do {
                    let encoder = JSONEncoder()
                    let jsonData: Data = try encoder.encode(data)
                    let decoder = JSONDecoder()
                    let model = try decoder.decode(__TranslateResponse.self, from: jsonData)
                    guard let translatedText = model.translations.first?.translatedText else {
                        completion(.faild(err: ARRequestError.modelConvertError(error: nil)))
                        return
                    }
                    completion(.success(model: translatedText))
                } catch {
                    completion(.faild(err: .modelConvertError(error: error)))
                }
            }
        }
    }
}
